﻿using blackhouse.BlackApart.Business.ApartmentServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace blackhouse.BlackApart.Business.Prices {
    public class PriceWithAdditionalServices : IApartmentPrice {

        #region Fields

        private readonly IApartmentPrice price;
        private readonly List<IAdditionalService> services;

        #endregion

        public PriceWithAdditionalServices(IApartmentPrice price, params IAdditionalService[] services) {
            this.price = price;
            this.services = new List<IAdditionalService>(services);
        }

        public int ReservationNumberOfPeoples {
            get {
                return this.price.ReservationNumberOfPeoples + 1;
            }
            set {
                this.price.ReservationNumberOfPeoples = value - 1;
            }
        }

        public DateTime ReservationFromDay {
            get {
                return this.price.ReservationFromDay;
            }
            set {
                this.price.ReservationFromDay = value;
            }
        }

        public DateTime ReservationToDay {
            get {
                return this.price.ReservationToDay;
            }
            set {
                this.price.ReservationToDay = value;
            }
        }

        public double GetApartmentPrice() {
            return this.price.GetPrice();
        }

        public double GetApartmentPriceWithoutRabat() {
            return this.price.GetPriceWithoutRabat();
        }

        public double GetPrice() {
            return this.GetServicePrice() + this.price.GetPrice();
        }

        public double GetPriceWithoutRabat() {
            return this.GetServicePrice() + this.price.GetPriceWithoutRabat();
        }

        public float GetRabatValue() {
            return this.price.GetRabatValue();
        }

        public void ApplyPriceRabat(IPriceRabat rabat) {
            this.price.ApplyPriceRabat(rabat);
        }

        public IPriceRabat[] GetAssociacedRabats() {
            return this.price.GetAssociacedRabats();
        }

        public double GetServicePrice() {
            var reservationDays = (int)(this.ReservationToDay.Date - this.ReservationFromDay.Date).TotalDays;
            double servicePrice = 0;
            foreach (IAdditionalService additionalService in this.services) {
                servicePrice +=
                    new DefaultAdditionalServicePrice(additionalService, reservationDays,
                        this.ReservationNumberOfPeoples).Price;
            }
            return servicePrice;
        }

        public double GetServicePrice(IAdditionalService priceForService) {
            var reservationDays = (int)(this.ReservationToDay.Date - this.ReservationFromDay.Date).TotalDays;
            var service = this.services.FirstOrDefault(s => s.ServiceId == priceForService.ServiceId);
            return service != null ?
                new DefaultAdditionalServicePrice(service, reservationDays, this.ReservationNumberOfPeoples).Price
                : 0;
        }

        public IEnumerable<IAdditionalService> GetServices() {
            return this.services;
        }

        public bool HaveService(string serviceKey) {
            return this.services.Any(s => s.ServiceKey == serviceKey);
        }

        public void AddService(IAdditionalService additionalService) {
            this.services.Add(additionalService);
        }

    }
}
